﻿using System;
using System.Linq;
using System.Net.NetworkInformation;
using Kaleida.ServiceMonitor.Operations.PreparedRequests;
using NUnit.Framework;
using Ping = Kaleida.ServiceMonitor.Operations.PreparedRequests.Ping;

namespace Kaleida.UnitTests.Operations.PreparedRequests
{
	[TestFixture]
	public class PingTests
	{
		[Test]
		public void TestBuildData()
		{
			var expected = new byte[]
			               	{
			               		0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
								0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
								0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x61,
								0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69
			               	};

			var data = Ping.BuildData(32);
			Assert.AreEqual(expected, data);
			Assert.AreEqual("abcdefghijklmnopqrstuvwabcdefghi", string.Concat(data.Select(i=>(char)i)));

			Assert.AreEqual("a", string.Concat(Ping.BuildData(1).Select(i => (char)i)));
			Assert.AreEqual("abcdefghijklmnopqrstuvw", string.Concat(Ping.BuildData(23).Select(i => (char)i)));
			Assert.AreEqual("abcdefghijklmnopqrstuvwabcdefghijklmnopqrstuvwabcdefghijklmnopqr", string.Concat(Ping.BuildData(64).Select(i => (char)i)));
		}

		[Test]
		public void TestSuccess()
		{
			var response = Ping.ProcessReply("server", new byte[] { 0x0, 0x1, 0xa, 0xb }, IPStatus.Success, new byte[] { 0x0, 0x1, 0xa, 0xb }, 10);
			Assert.IsTrue(response.Success);
			Assert.AreEqual(10, response.TimeTaken.TotalMilliseconds);
			Assert.AreEqual("Success", response.Content);
			Assert.AreEqual("Ping completed with status Success in 10ms", response.ToString());
		}

		[Test]
		public void TestTimeout()
		{
			var response = Ping.ProcessReply("server", new byte[] { 0x0, 0x1, 0xa, 0xb }, IPStatus.TimedOut, new byte[] { 0x0, 0x1, 0xa, 0xb }, 5000);
			Assert.IsFalse(response.Success);
			Assert.AreEqual(typeof(PingTimedOutException), response.Exception.GetType());
			Assert.AreEqual("Ping to server timed out", response.Exception.Message);
			Assert.AreEqual("An Exception occured: Ping to server timed out", response.Content);
			Assert.AreEqual("An Exception occured: Ping to server timed out", response.ToString());
		}

		[Test]
		public void TestResponseIsExceptionIfResponseBufferDifferentToSendBuffer()
		{
			var response = Ping.ProcessReply("server", new byte[] { 0x0, 0x1, 0xa, 0xb }, IPStatus.Success, new byte[] { 0x0, 0x1, 0xa, 0xc }, 10);
			Assert.IsFalse(response.Success);
			Assert.AreEqual("An Exception occured: Ping response buffer did not match send buffer.\r\nSend buffer: 00 01 0a 0b\r\nResponse Buffer: 00 01 0a 0c", response.Content);
			Assert.AreEqual(typeof(PingReplyUnexpectedBufferException), response.Exception.GetType());
			Assert.AreEqual("Ping response buffer did not match send buffer.\r\nSend buffer: 00 01 0a 0b\r\nResponse Buffer: 00 01 0a 0c", response.Exception.Message);
			Assert.AreEqual("An Exception occured: Ping response buffer did not match send buffer.\r\nSend buffer: 00 01 0a 0b\r\nResponse Buffer: 00 01 0a 0c", response.ToString());
		}
	}
}
